function [bci, bciDat]=bciGetOfflineData(bci,bciDatOrig)

global MEMepoch;

blocksize = 10;% round(bci.srate *0.1); % 1s when choosing samprate
% % initialize data
% bci=bciInit(bci);

isFeedbackRun=isfield(bciDatOrig,'testEvents');
if isFeedbackRun,
    isFeedbackRun=true;
    bciDatOrig.eventTime = bciDatOrig.testEvents(1,:);
    if(size(bciDatOrig.testEvents,1)==2),
        bciDatOrig.events = bciDatOrig.testEvents(2,:);
    else
        bciDatOrig.events = double(bciDatOrig.testEvents(2,:)<bciDatOrig.testEvents(3,:))*2+1;
    end
end
if isfield(bciDatOrig,'eventTime'),
    eventTime = bciDatOrig.eventTime;
    % get offset for start event
    startOffset=bciDatOrig.eventTime(1);
    % determine eventDur
    bci.eventDur = diff([bciDatOrig.eventTime bciDatOrig.eventTime(end)]);
    % estimate size
    trainRunDur = sum(bci.eventDur)+bci.preRunDur;
else
    trainRunDur = bci.testRunDur+bci.preRunDur;
end
% nData = round((trainRunDur+10) * bci.srate);
nRTsamp=round(bci.RT*bci.srate);
nRetrainSamp = floor(bci.paradigm.fbClassifierTrialLength*bci.param.winsrate);

nEpochs = round((max(bci.testRunDur,trainRunDur)-length(bci.events)*bci.RT+10)*bci.init.epochRate);

epochLabel = zeros(1,nEpochs);
epochOnset = zeros(1,nEpochs);
epochTrialID = zeros(1,nEpochs);
badChanMap = zeros(length(bci.preprocChan),nEpochs);
isRetrainTrial = false(1,nEpochs);

% now run can begin
lastEventSamp=inf;
lastTrialReset=inf;
eventCount=0;
eventChanged=true;
prevTrainSample = 0;
datCount=1;
epochCount = 0;
curEvent=0;
trialCount = 0;
stimCount = 0;

timeToAddToOnset=bci.eventDur;
if bci.paradigm.id >2 && bci.paradigm.id <10,
    timeToAddToOnset(bciDatOrig.events==bci.baseEvent)=...
        min(timeToAddToOnset(bciDatOrig.events==bci.baseEvent),bci.fixDur);
    timeToAddToOnset(bciDatOrig.events==bci.leftEvent|bciDatOrig.events==bci.rightEvent)=...
        min(timeToAddToOnset(bciDatOrig.events==bci.leftEvent|bciDatOrig.events==bci.rightEvent),min(bci.movDur));
end
if bci.paradigm.id <10,
    startStimEvents = bci.eventsToClassify;
else
    startStimEvents = 8; % flicker start event
end
trigData = bciDatOrig.trainDat(bci.init.trigChan,:);
if bci.paradigm.id==12||bci.paradigm.id==14,
    % remove P300 paradigm synchronization trigger
    trigData(trigData==bci.paradigm.flashSyncTrigger)=0;
end

while  datCount+blocksize<=size(bciDatOrig.trainDat,2),% eventCount<length(bciDatOrig.events)&&
    if bci.param.doReceiveTrigger && isfield(bci.init,'trigChan')&&~isempty(bci.init.trigChan), % use trigger channel for event determination
        trigIdx = find(diff(trigData(datCount:datCount+blocksize))>0);
        for k=1:length(trigIdx),
            lastEventSamp=datCount+trigIdx(k);
            lastEvent = trigData(lastEventSamp);
            if lastEvent>2^14, lastEvent=lastEvent-2^14; end % solves MEG trigger bug
            eventChanged=true;
            if any(lastEvent==bciDatOrig.events),
                eventCount = eventCount+1;
            end
            if any(lastEvent==startStimEvents),
                lastTrialReset = epochCount+1;
                stimCount = stimCount +1;
            end
            if any(lastEvent == bci.eventsToClassify),
                lastStimEvent = lastEvent;
            end
        end
    else
        tmp = find((datCount/bci.srate-startOffset)<=cumsum(bci.eventDur),1);
        if isempty(tmp),
            tmp=length(bciDatOrig.events);
        end
        if tmp~=eventCount,
            eventCount = tmp;
            lastEvent=bciDatOrig.events(eventCount);
            lastEventSamp=round(eventTime(eventCount)*bci.srate);
            eventChanged=true;
            if any(lastEvent==startStimEvents),
                lastTrialReset = epochCount+1;
                stimCount = stimCount +1;
            end
            if any(lastEvent == bci.eventsToClassify),
                lastStimEvent = lastEvent;
            end
        end
    end
    if eventChanged,
        % set next expected classifier window onset to event onset
        prevTrainSample = lastEventSamp + nRTsamp - bci.init.nOffset+1;
        eventChanged=false;
        trialCount = trialCount +1;
    end
    datCount=datCount+blocksize;
    while datCount > prevTrainSample+bci.init.nEpochLength,
        % if prevTrainSample/bci.srate-eventTime(eventCount)>= bci.RT
        if prevTrainSample+bci.init.nOffset-lastEventSamp > nRTsamp && ...
                prevTrainSample+bci.init.nOffset-lastEventSamp < bci.srate*timeToAddToOnset(eventCount) && ...
                any(startStimEvents==lastEvent),
            % get next block
            curEpochIdx = prevTrainSample+1:prevTrainSample+bci.init.nEpochLength;
            if bci.init.doNoiseCancellation,
                curEpochData = bciNoiseCancellation(...
                    double(bciDatOrig.trainDat(bci.preprocChan,curEpochIdx)),...
                    double(bciDatOrig.trainDat(bci.referenceChan,curEpochIdx)));
            else
                curEpochData = bciDatOrig.trainDat(bci.preprocChan,curEpochIdx);
            end
            epochCount = epochCount + 1;
            if bci.paradigm.id==12||bci.paradigm.id==14,
%                 if curEvent==90,keyboard;end
                syncOnsets = bciP3Synchronize(bci,bciDatOrig.trainDat(bci.init.trigChan,curEpochIdx),...
                    bciDatOrig.trainDat(bci.init.respChan,curEpochIdx),...
                    bciDatOrig.stim, lastStimEvent, stimCount);
                [ep badChan] = bciGetP3Epochs(bci,curEpochData,bciDatOrig.stim,syncOnsets,stimCount);
            else

                [ep badChan] = bciGetEpoch(bci,curEpochData);
            end
            MEMepoch(:,:,epochCount) = ep;
            epochLabel(epochCount) = lastStimEvent;
            epochOnset(epochCount) = prevTrainSample+1;
            badChanMap(:,epochCount) = badChan;
            epochTrialID(epochCount) = trialCount;
            isRetrainTrial(epochCount)=epochCount<(lastTrialReset+nRetrainSamp);
        end
        prevTrainSample = prevTrainSample+bci.init.nWinShift;
        if eventCount>curEvent,
            fprintf('%d %i %i %3.3f \n', eventCount,lastStimEvent,lastEvent,lastEventSamp/bci.srate);
            curEvent=eventCount;
        end
    end
end % while true

fprintf('\n')

bciDat.nEpochs = epochCount;

bciDat.trainLabel=epochLabel(1:epochCount);
if isFeedbackRun,
    bciDat.isRetrainTrial=isRetrainTrial(1:epochCount);
    bciDat.testEvents=bciDatOrig.testEvents;
    bciDat.testOnset=bciDatOrig.testOnset;
end
bciDat.trainOnset=epochOnset(1:epochCount);
bciDat.badChanMap=badChanMap(:,1:epochCount);
bciDat.trialID=epochTrialID(1:epochCount);
